package com.xzcedu.jdbc.datasource;

import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;
import org.junit.jupiter.api.Test;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;

/**
 * @author 徐州城
 * @version 1.0
 */
public class DBUtils_USE {

    //使用 apache-DBUtils 工具类 + druid，完成对表的CRUD操作
    @Test
    public void testQueryMany() throws SQLException {//返回结果是多行的情况

        //1. 得到连接
        Connection connection = JDBCUtilsByDruid.getConnection();
        //2. 使用 DBUtils 类和接口，先引入 DBUtils相关的jar ，加入到本Project
        //3. 创建一个 QueryRunner
        QueryRunner queryRunner = new QueryRunner();
        //4. 就可以执行相关的方法，返回ArrayList结果集
//        String sql = "select * from actor where id >= ?";
        //  注意：sql 语句也可以查询部分列
        String sql = "select id,name from actor where id >= ?";

        //解读
        //(1) query 方法执行了sql 语句，得到result --f封装到 ---> ArrayList集合中
        //(2) 返回集合
        //(3) connection: 连接
        //(4) sql: 执行的sql语句
        //(5) new BeanListHandler<>(Actor.class): 在将resultSet-> Actor对象 -> 封装到ArrayList
        //    底层使用反射机制 去获取Actor 类的属性，然后进行封装
        //(6) 1: 就是给sql 语句中的? 赋值，可以有多个值，因为是可变参数
        //(7) 底层得到的result，会在query 关闭，也会关闭PreparedStatement
        /**
         * 分析 queryRunner.query方法:
         * public <T> T query(Connection conn, String sql, ResultSetHandler<T> rsh, Object... params) throws SQLException {
         *         PreparedStatement stmt = null; //定义PreparedStatement
         *         ResultSet rs = null; //接受返回的  ResultSet
         *         Object result = null; //返回ArrayList
         *
         *         try {
         *             stmt = this.prepareStatement(conn, sql); //创建PreparedStatement
         *             this.fillStatement(stmt, params); //对sql 进行? 赋值
         *             rs = this.wrap(stmt.executeQuery()); //执行sql，返回resultSet
         *             result = rsh.handle(rs); //返回的result --> ArrayList [使用到反射，对传入的class对象处理]
         *         } catch (SQLException var33) {
         *             this.rethrow(var33, sql, params);
         *         } finally {
         *             try {
         *                 this.close(rs); //关闭resultSet
         *             } finally {
         *                 this.close((Statement)stmt); //关闭preparedStatement对象
         *             }
         *         }
         *
         *         return result;
         *     }
         */
        List<Actor> list =
                queryRunner.query(connection, sql, new BeanListHandler<>(Actor.class), 1);

        System.out.println("输入集合的信息");
        for (Actor actor : list) {
            System.out.print(actor);
        }

        //释放资源
        JDBCUtilsByDruid.close(null, null, connection);
    }

    @Test
    //演示 apache-dbUtils + druid 完成 返回的结果是单行的记录(一行对象)
    public void testQuerySingle() throws SQLException {
        //1. 得到连接
        Connection connection = JDBCUtilsByDruid.getConnection();
        //2. 使用 DBUtils 类和接口，先引入 DBUtils相关的jar ，加入到本Project
        //3. 创建一个 QueryRunner
        QueryRunner queryRunner = new QueryRunner();
        //4. 就可以执行相关的方法，返回单个对象
        String sql = "select * from actor where id = ?";

        //解读: 因为返回的是单行记录 ，使用BeanHandler
        Actor actor = queryRunner.query(connection, sql, new BeanHandler<>(Actor.class), 2);
        System.out.println(actor);

        //释放资源
        JDBCUtilsByDruid.close(null, null, connection);
    }

    @Test
    //演示 apache-dbUtils + druid，完成查询返回的结果是单行单列-返回的就是 object
    public void testScalar() throws SQLException {
        //1. 得到连接
        Connection connection = JDBCUtilsByDruid.getConnection();
        //2. 使用 DBUtils 类和接口，先引入 DBUtils相关的jar ，加入到本Project
        //3. 创建一个 QueryRunner
        QueryRunner queryRunner = new QueryRunner();
        //4. 执行相关的方法，返回单行单列
        String sql = "select name from actor where id = ?";

        //解读: 因为返回的是一个对象，使用的handler 就是
        Object obj = queryRunner.query(connection, sql, new ScalarHandler(), 2);
        System.out.println(obj);

        //释放资源
        JDBCUtilsByDruid.close(null, null, connection);
    }


    @Test
    //演示 apache-dbUtils + druid，完成 dml (CRUD)
    public void testDML() throws SQLException {
        //1. 得到连接
        Connection connection = JDBCUtilsByDruid.getConnection();
        //2. 使用 DBUtils 类和接口，先引入 DBUtils相关的jar ，加入到本Project
        //3. 创建一个 QueryRunner
        QueryRunner queryRunner = new QueryRunner();
        //4. 组织sql语句，完成 insert, update, delete

        //String sql = "update actor set name = ? where id = ?";
        //String sql = "insert into actor values(null, ?, ?, ?, ?)";
        String sql = "delete from actor where id = ?";
        /*
            解释
            1. 执行dml 操作是 queryRunner.update()
            2. 返回值是受影响的行数
         */
        int affectedRow = queryRunner.update(connection, sql, 11);
        System.out.println(affectedRow > 0 ? "执行成功" : "执行没有影响到表");


        //释放资源
        JDBCUtilsByDruid.close(null, null, connection);
    }

}
